package com.power.poi.excel;

import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;

import java.util.Iterator;

public class ExcelCopyUtil {

    /**
     * Copy a cell style to the destination cell style
     *
     * @param fromStyle source cell style
     * @param toStyle   target cell style
     */
    public static void copyCellStyle(CellStyle fromStyle, CellStyle toStyle) {
        try {
            toStyle.cloneStyleFrom(fromStyle);
        } catch (Exception e) {
            throw new RuntimeException("Currently version can't copy cell with data,please remove data from your template");
        }

//        toStyle.setAlignment(fromStyle.getAlignmentEnum());
//        //copy border and border color
//        toStyle.setBorderBottom(fromStyle.getBorderBottomEnum());
//        toStyle.setBorderLeft(fromStyle.getBorderLeftEnum());
//        toStyle.setBorderRight(fromStyle.getBorderRightEnum());
//        toStyle.setBorderTop(fromStyle.getBorderTopEnum());
//        toStyle.setTopBorderColor(fromStyle.getTopBorderColor());
//        toStyle.setBottomBorderColor(fromStyle.getBottomBorderColor());
//        toStyle.setRightBorderColor(fromStyle.getRightBorderColor());
//        toStyle.setLeftBorderColor(fromStyle.getLeftBorderColor());
//
//        //copy Background and ForegroundColor
//        toStyle.setFillBackgroundColor(fromStyle.getFillBackgroundColor());
//        toStyle.setFillForegroundColor(fromStyle.getFillForegroundColor());
//
//        toStyle.setDataFormat(fromStyle.getDataFormat());
//        toStyle.setFillPattern(fromStyle.getFillPatternEnum());
//
//        //toStyle.setFont(fontIndex);
//        toStyle.setHidden(fromStyle.getHidden());
//        // Indention
//        toStyle.setIndention(fromStyle.getIndention());
//        toStyle.setLocked(fromStyle.getLocked());
//        toStyle.setRotation(fromStyle.getRotation());//Rotation
//        toStyle.setVerticalAlignment(fromStyle.getVerticalAlignmentEnum());
//        toStyle.setWrapText(fromStyle.getWrapText());
    }

    /**
     * Copy a sheet to a target sheet
     *
     * @param fromSheet     source sheet
     * @param toSheet       target sheet
     * @param copyValueFlag If this is true only, it will be copied along with the value
     */
    public static void copySheet(Workbook wb, Sheet fromSheet, Sheet toSheet, boolean copyValueFlag) {

        //handle merge region
        mergerRegion(fromSheet, toSheet);
        for (Iterator rowIt = fromSheet.rowIterator(); rowIt.hasNext(); ) {
            Row tmpRow = (Row) rowIt.next();
            Row newRow = toSheet.createRow(tmpRow.getRowNum());
            //set column with
            int cellNum = tmpRow.getLastCellNum();
            for (int i = 0; i < cellNum; i++) {
                toSheet.setColumnWidth(i, fromSheet.getColumnWidth(i));
            }
            //copy row
            copyRow(wb, tmpRow, newRow, copyValueFlag);
        }
    }

    /**
     * copy row to target row
     *
     * @param fromRow source row
     * @param toRow   target row
     */
    public static void copyRow(Workbook wb, Row fromRow, Row toRow, boolean copyValueFlag) {
        //set height
        toRow.setHeightInPoints(fromRow.getHeightInPoints());
        for (Iterator cellIt = fromRow.cellIterator(); cellIt.hasNext(); ) {
            Cell tmpCell = (Cell) cellIt.next();
            Cell newCell = toRow.createCell(tmpCell.getColumnIndex());
            copyCell(wb, tmpCell, newCell, copyValueFlag);
        }
    }

    /**
     * Copy the merged cell of the original sheet to the newly created sheet
     *
     * @param fromSheet source sheet
     * @param toSheet   target sheet
     */
    public static void mergerRegion(Sheet fromSheet, Sheet toSheet) {
        int sheetMergerCount = fromSheet.getNumMergedRegions();
        for (int i = 0; i < sheetMergerCount; i++) {
            CellRangeAddress mergedRegionAt = fromSheet.getMergedRegion(i);
            toSheet.addMergedRegion(mergedRegionAt);
        }
    }

    /**
     * Copy a cell to a target cell
     *
     * @param srcCell       source cell
     * @param distCell      target cell
     * @param copyValueFlag If this is true only, it will be copied along with the value
     */
    public static void copyCell(Workbook wb, Cell srcCell, Cell distCell, boolean copyValueFlag) {
        CellStyle newStyle = wb.createCellStyle();
        newStyle.setDataFormat(srcCell.getCellStyle().getDataFormat());
        copyCellStyle(srcCell.getCellStyle(), newStyle);


        //set cell style
        distCell.setCellStyle(newStyle);
        //set comment
        if (srcCell.getCellComment() != null) {
            distCell.setCellComment(srcCell.getCellComment());
        }

        CellType srcCellType = srcCell.getCellTypeEnum();
        distCell.setCellType(srcCellType);
        if (copyValueFlag) {
            if (srcCellType == CellType.NUMERIC) {
                if (HSSFDateUtil.isCellDateFormatted(srcCell)) {
                    distCell.setCellValue(srcCell.getDateCellValue());
                } else {
                    distCell.setCellValue(srcCell.getNumericCellValue());
                }
            } else if (srcCellType == CellType.STRING) {
                distCell.setCellValue(srcCell.getRichStringCellValue());
            } else if (srcCellType == CellType.BLANK) {
                // nothing21
            } else if (srcCellType == CellType.BOOLEAN) {
                distCell.setCellValue(srcCell.getBooleanCellValue());
            } else if (srcCellType == CellType.ERROR) {
                distCell.setCellErrorValue(srcCell.getErrorCellValue());
            } else if (srcCellType == CellType.FORMULA) {
                distCell.setCellFormula(srcCell.getCellFormula());
            } else {
                //nothing
            }
        }
    }
}
